单例模式 单例模式(Singleton)作用 :
可以保证的程序运行过程,一个类只有一个示例,并提供一个访问它的全局访问点方便外界访问
控制了实例个数,并节约系统资源。
单例写法有好几种,通常的写法是基于线程安全的写法,保证单例对象只会被创建一次,为单例对象创建一个静态实例,可以写成全局的,也可以在类方法中实现,并置为nil。
简要步骤
1、先定义一个静态的instance.
2、定一个sharedInstance的类方法.能够被全局调用的.此方法里需要考虑线程安全问题
3、如果需要copy,需要遵守NSCopying协议,以及在copyWithZone中,直接返回self;
创建一个继承继承自NSObject的类AccountManager
AccountManager.h文件
1 2 3 4 5 6 7 8 9 10 11 12 #import <Foundation/Foundation.h> @interface AccountManager : NSObject + (instancetype )sharedInstance; @end
AccountManager.m文件(简洁版,不考虑alloc,copy方式创建单例)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 #import "AccountManager.h" @implementation AccountManager static AccountManager *_sharedInstance = nil ;#pragma mark---创建单例(普通,同步锁,GCD三种方式) + (instancetype )sharedInstance1{ if (!_sharedInstance) { _sharedInstance = [[self alloc]init]; } return _sharedInstance; } + (instancetype )sharedInstance{ @synchronized (self ) { if (!_sharedInstance) { _sharedInstance = [[self alloc] init]; } } return _sharedInstance; } static dispatch_once_t onceToken;+ (instancetype )sharedInstance2 { dispatch_once (&onceToken, ^{ _sharedInstance = [[self alloc] init]; }); return _sharedInstance; } #pragma mark---销毁单例 +(void )attemptDealloc{ _sharedInstance = nil ; } +(void )attempDealloc{ onceToken = 0 ; _sharedInstance = nil ; }
这样就是一个完整的单例,保证怎么创建都是唯一的.
测试单例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - (void )viewDidLoad { [super viewDidLoad]; AccountManager *obj1 = [AccountManager sharedInstance] ; NSLog (@"obj1 = %@" , obj1) ; AccountManager *obj2 = [AccountManager sharedInstance] ; NSLog (@"obj2 = %@" , obj2) ; AccountManager *obj3 = [[AccountManager alloc] init] ; NSLog (@"obj3 = %@" , obj3) ; AccountManager* obj4 = [[AccountManager alloc] init] ; NSLog (@"obj4 = %@" , [obj4 copy ]) ; }
打印详情
1 2 3 4 2016-03-12 14:30:52.078030+0800 SingletonDemo[3438:763080] obj1 = <AccountManager: 0x60400001dfb0> 2016-03-12 14:30:52.078208+0800 SingletonDemo[3438:763080] obj2 = <AccountManager: 0x60400001dfb0> 2016-03-12 14:30:52.078340+0800 SingletonDemo[3438:763080] obj3 = <AccountManager: 0x60000001e230> 2016-03-12 14:30:52.078340+0800 SingletonDemo[3438:763080] obj4 直接Crash
以上创建单例方式基本可以了,通过alloc,copy方式创建单例本身就是一种非规范写法,但为了提高容错率,我们还是处理下alloc,copy方式创建单例。
升级版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 #import "AccountManager.h" @implementation AccountManager static AccountManager *_sharedInstance = nil ;+ (instancetype )sharedInstance1{ if (!_sharedInstance) { _sharedInstance = [[self alloc]init]; } return _sharedInstance; } + (instancetype )sharedInstance{ @synchronized (self ) { if (!_sharedInstance) { _sharedInstance = [[super allocWithZone:NULL ] init]; } } return _sharedInstance; } static dispatch_once_t onceToken;+ (instancetype )sharedInstance2 { dispatch_once (&onceToken, ^{ _sharedInstance = [[self alloc] init]; }); return _sharedInstance; } #pragma mark---销毁单例 +(void )attemptDealloc1{ _sharedInstance = nil ; } +(void )attempDealloc2{ onceToken = 0 ; _sharedInstance = nil ; } #pragma mark---完善alloc,copy方式创建的单例 + (instancetype )allocWithZone:(struct _NSZone *)zone { return [self sharedInstance]; } + (id )copyWithZone:(struct _NSZone *)zone { return [self sharedInstance]; } - (id )copy { return self ; } - (id )mutableCopy { return self ; } @end
测试打印信息:
1 2 3 4 2016-03-12 14:53:17.572240+0800 SingletonDemo[3995:849854] obj1 = <AccountManager: 0x600000007850> 2016-03-12 14:53:17.572624+0800 SingletonDemo[3995:849854] obj2 = <AccountManager: 0x600000007850> 2016-03-12 14:53:17.572768+0800 SingletonDemo[3995:849854] obj3 = <AccountManager: 0x600000007850> 2016-03-12 14:53:17.572909+0800 SingletonDemo[3995:849854] obj4 = <AccountManager: 0x600000007850>